<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。JCAT 由中国团队开发维护。
//  正在使用的这个版本是：0.4.0 / SVN信息: $Id: class._JCAT_Caller.php 1490 2009-03-19 12:38:51Z alee $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [下载(HTTP)] http://code.google.com/p/jcat-php/downloads/list
//    [下载(svn)] svn checkout http://jcat-php.googlecode.com/svn/branches/0.4.0/Framework/ JCAT0.4
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.com/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.com/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/




/**
 * 此类对调用者进行递归描述
 *
 * @author		alee
 * @access		private
 */
class _JCAT_Caller
{


	/**
	 * 构造函数
	 * 
	 * @access	public
	 * @param	$arrBacktrace		array	_JCAT_ExecutingStack::GetBacktrace() 返回的数组
	 * @return	
	 */
	public function _JCAT_Caller( array $arrBacktrace ) 
	{
		JCAT_ASSERT::ASSERT_( (isset($arrBacktrace['by']) and $arrBacktrace['by']=='JCAT_Backtrace' ),
				JCAT_Language::SentenceEx("参数 \$arrBacktrace 必须是 static JCAT_Backtrace::GetBacktrace() 返回的数组。",'JCAT',null) ) ;
		JCAT_ASSERT::ASSERT_( count($arrBacktrace)>=3 ,
				JCAT_Language::SentenceEx('参数 $arrBacktrace 无效，在参数 $arrBacktrace 中，没有调用者的有关信息，目标栈可能不在任何调用路径上','JCAT',null) ) ;
		
		
		// 被调用栈
		$this->aBeCalledStack = new _JCAT_ExecutingStack($arrBacktrace) ;
		JCAT_ASSERT::ASSERT_INSTANCE($this->aBeCalledStack,'_JCAT_ExecutingStack') ;
	
	
		// 调用发生点
		array_shift($arrBacktrace) ;
		$this->aCallPoint = new _JCAT_ExecutingPoint($arrBacktrace) ;
		JCAT_ASSERT::ASSERT_INSTANCE($this->aCallPoint,'_JCAT_ExecutingPoint') ;
		
		
		// 递归创建 调用者 的 调用者
		while( count($arrBacktrace)>=3 )
		{
			$aParentCaller = new self($arrBacktrace) ;

			// 排除 call_user_func 等 多余 backtrace
			$sFunction = strtolower($aParentCaller->GetFunction()) ;
			if( !$aParentCaller->GetClass() and in_array( $sFunction, array('call_user_func','call_user_func_array','eval') ) )
			{
				array_shift($arrBacktrace) ;
				continue ;
			}

			else
			{
				$this->aParentCaller = $aParentCaller ;
				break ;
			}
		}
	}



	/**
	 * 返回调用者 的 调用者 （职责链模式）
	 * 
	 * @access	public
	 * @return	_JCAT_Caller
	 */
	public function GetCaller(  ) 
	{ return $this->aParentCaller ; }



	/**
	 * 取得 调用点
	 * 
	 * @access	public
	 * @return	_JCAT_ExecutingPoints
	 */
	public function GetCallPoint(  ) 
	{ return $this->aCallPoint ; }



	/**
	 * 取得被调用的栈
	 * 
	 * @access	public
	 * @return	_JCAT_ExecutingStack
	 */
	public function GetCalledStack(  ) 
	{ return $this->aBeCalledStack ; }


	/**
	 * 取得调用者所在包的ID。 调用者必须属于一个类，并且此类已经通过 JCAT_Package::RegisterClassID() 注册到一个包
	 * 
	 * @access	public
	 * @return	int
	 */
	public function GetPackageID()
	{ return $this->aCallPoint->GetPackageID() ;}

	/**
	 * 取得调用者 所属的 类
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetClass(  ) 
	{ return $this->aCallPoint->GetClass() ;}



	/**
	 * 取得调用者 所属的函数（或方法）
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetFunction(  ) 
	{ return $this->aCallPoint->GetFunction() ;}



	/**
	 * 取得调用者 所在的文件
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetFile(  ) 
	{ return $this->aCallPoint->GetFile() ;}


	/**
	 * 取得调用发生点 所在行
	 * 
	 * @access	public
	 * @return	int
	 */
	public function GetLineForCall(  ) 
	{ return $this->aCallPoint->GetLine() ;}



	/**
	 * 取得调用栈所在包的ID。 调用栈必须属于一个类，并且此类已经通过 JCAT_Package::RegisterClassID() 注册到一个包
	 * 
	 * @access	public
	 * @return	int
	 */
	public function GetCalledPackageID()
	{ return $this->aBeCalledStack->GetPackageID() ;}

	/**
	 * 取得 被调用栈 所属的类
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetCalledClass(  ) 
	{ return $this->aBeCalledStack->GetClass() ;}



	/**
	 * 取得 被调用栈 所属的函数（或方法）
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetCalledFunction(  ) 
	{ return $this->aBeCalledStack->GetFunction() ;}



	/**
	 * 取得调用者 所在的文件
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetCalledFile(  ) 
	{ return $this->aBeCalledStack->GetFile() ;}




	// 属性 ///////////////////////////////////////////////////////////////////////////////

	/**
	 * 被调用的栈
	 * 
	 * @access	private
	 * @var		_JCAT_ExecutingPoints
	 */
	private $aCallPoint ;

	/**
	 * 调用点
	 * 
	 * @access	private
	 * @var		_JCAT_ExecutingStack
	 */
	private $aBeCalledStack ;

	/**
	 * 调用者 的  调用者 （递归引用）
	 * 
	 * @access	private
	 * @var		_JCAT_Caller
	 */
	private $aParentCaller ;


}
/*macro_exception_code:0*/
?>